using System;
using System.Collections.Generic;
using System.Text;

namespace TinyOsMessageForwarder
{
    public class TinyOSMessage
    {
        public static readonly int MAX_LENGTH = 36;
        public const UInt16 BROADCAST_ADDRESS = 0xFFFF;

        private byte[] message;

        public byte[] RawMessage
        {
            get { return message; }
        //    set { message = value; }
        }

        //        byte ptr;
        public TinyOSMessage()
        {
            message = new byte[5 + MAX_LENGTH];
        }

        public TinyOSMessage(byte[] rawMessage)
        {
            message = rawMessage; //TODO: check length, ...
        }

        public UInt16 Address
        {
            get
            {
                return ReadUInt16(0);
            }
            set
            {
                WriteUInt16(0, value);
            }
        }

        public byte AMType
        {
            get
            {
                return ReadUInt8(2);
            }
            set
            {
                WriteUInt8(2, value);
            }
        }

        public byte Group
        {
            get
            {
                return ReadUInt8(3);
            }
            set
            {
                WriteUInt8(3, value);
            }
        }

        public byte Length
        {
            get
            {
                return ReadUInt8(4);
            }
            set
            {
                WriteUInt8(4, value);
            }
        }


        public void ResetData()
        {
            //            ptr = 5;
        }

        protected void WriteUInt8(byte offset, byte x)
        {
            message[offset] = x;
        }

        protected byte ReadUInt8(byte offset)
        {
            return message[offset];
        }

        protected void WriteUInt16(byte offset, UInt16 x)
        {
            message[offset] = (byte)(x & 0xFF);
            message[offset + 1] = (byte)((x >> 8) & 0xFF);
        }

        protected UInt16 ReadUInt16(byte offset)
        {
            return (UInt16) (message[offset] + (((UInt16)(message[offset + 1])) << 8));
        }

        protected void WriteUInt32(byte offset, UInt32 x)
        {
            message[offset] = (byte)(x & 0xFF);
            message[offset + 1] = (byte)((x >> 8) & 0xFF);
            message[offset + 2] = (byte)((x >> 16) & 0xFF);
            message[offset + 3] = (byte)((x >> 24) & 0xFF);
        }

        protected UInt32 ReadUInt32(byte offset)
        {
            return ReadUInt16(offset) + (((UInt32)ReadUInt16((byte)(offset + 2))) << 16);
        }
    }
}
